package wfm.managedbean;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import org.activiti.engine.HistoryService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.stereotype.Controller;
import wfm.activiti.ActivitiManager;
import wfm.activiti.util.TaskIdComparator;
import wfm.bean.Address;
import wfm.bean.Customer;
import wfm.bean.Ticket;
import wfm.bean.User;
import wfm.query.QueryDao;
import com.constants.Constants;
import com.web.util.RegisteredUsers;
import com.web.util.WebUtils;


@ManagedBean(name="startMBean")
@SessionScoped
@Controller
public class StartMBean {

	String testMe = "Hallo Test";
	String link1="http://localhost:63082/addressValidation/validateAddress?firstName=Max&lastName=Muster&street=Mustergasse%202&city=Wien&zip=1090&country=Austria&telNo=1234567";
	
	private String procId=null;
	
	private String nickname="b.mueller@realestate.com";
	private String password;
	
	private User user;
	
	private Customer customer = new Customer(new Address());
	private Ticket ticket=new Ticket(customer);
	
	private String customerText=null;
	private String finishedText=null;
	
	public String getCustomerText() {
		return customerText;
	}
	public void setCustomerText(String customerText) {
		this.customerText = customerText;
	}
	public String getFinishedText() {
		return finishedText;
	}
	public void setFinishedText(String finishedText) {
		this.finishedText = finishedText;
	}

	private String page = "";
	private String instanceId = "";
	private String taskId = "";
	
	public Customer getCustomer() { return this.customer; }
	public void setCustomers(Customer customer) { this.customer = customer; }
	
	public String getInstanceId() { return this.instanceId; }
	public void setInstanceId(String instanceId) { this.instanceId = instanceId; }
	
	public String getTaskId() { return this.taskId; }
	public void setTaskId(String taskId) { this.taskId = taskId; }
	
	public String getPage() { return page; }
	public void setPage(String page) { this.page = page; }
	
	public String getTestMe() {
		return testMe;
	}

	public void setTestMe(String testMe) {
		this.testMe = testMe;
	}

	public String getLink1() {
		return link1;
	}

	public void setLink1(String link1) {
		this.link1 = link1;
	}
	
	
	public String createTicket(){
		/*
		this.ticket = new Ticket();
		this.ticket.setCustomer(new Customer());
		this.ticket.getCustomer().setAddress(new Address());
		*/
		
		//FIXME: wieder zuruecksetzen
		this.ticket = new Ticket();
		this.ticket.setCustomer(new Customer("Max", "Muster", "Mustergasse 2", "Wien", "1090", "Austria", "1234567", "max@muster.at"));

		
		try{
			
			ActivitiManager manager = ActivitiManager.getInstance();
			manager.deployProcess(Constants.DEPLOY_PROCESS);
		    
			this.procId=manager.startProcess();    //Process Id in Session
			this.setInstanceId(this.procId);
			
			//System.out.println("instanceID erstellung: " + this.getInstanceId());
			
			List<Task> tasks=QueryDao.getAllTasks();
			
			Task t=null;
			
			if(tasks.size()>0){
				Collections.sort(tasks,new TaskIdComparator());
				t=tasks.get(0);  //holt sich letzten Task
				//System.out.println("TaskId: "+t.getId()+" will be assigned");
				this.setTaskId(t.getId());
				QueryDao.saveVariableToProcessWithTask(t,"test", "Hallo");
				//QueryDao.setAssigneeToTask(t, user.getUserName());
			}		
			
		}catch(RuntimeException t) {
			t.printStackTrace();
			//System.out.println("Prozess konnte nicht deployed werden");
		}
		
		
		return WebUtils.redirect("ticketCreation");
	}
	

	public String abortTicket(){

		Task t=QueryDao.getTaskById(this.getTaskId());
	
		if(t!=null){
			QueryDao.abortProcess(t);
		}
		
		return WebUtils.redirect("myTasks");
	}
	
	
	public String saveTicket(){
		
		String nextPage = "";
		
		Customer nCust;
		nCust=this.getTicket().getCustomer();
		
		// Retrieving form fields
		Map<String, String> prop = new HashMap<String, String>();
		prop.put("firstName", nCust.getFirstName());
		prop.put("lastName", nCust.getLastName());
		prop.put("street", nCust.getAddress().getStreet());
		prop.put("zip", nCust.getAddress().getZip());
		prop.put("city", nCust.getAddress().getCity());
		prop.put("country", nCust.getAddress().getCountry());
		prop.put("telNo", nCust.getTelNo());
		prop.put("mailAddress", nCust.getMailAddress());
		
		// Retrieving Activiti engine
		ActivitiManager manager = ActivitiManager.getInstance();	

		try {
		// Submitting task form
		String taskId=this.getTaskId();
		manager.getProcessEngine().getFormService().submitTaskFormData(taskId, prop);
		
		}
		catch(Throwable t){
			FacesContext fc = FacesContext.getCurrentInstance();
			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Problem with Webservice!!!", null);
		    fc.addMessage(null, msg);
		    fc.renderResponse();
		    
		    return "";
		}
		
		// Check for any execution errors
		String instanceId=this.getInstanceId();
		System.out.println("instanceID getTaskError: " + this.getInstanceId());
		String taskError = manager.getTaskError(instanceId);
		if (taskError != null && !taskError.equals(""))
		{	
			List<Task> tasks = manager.getProcessEngine().getTaskService().createTaskQuery().taskAssignee("kermit").processInstanceId(instanceId).list();
			if (tasks.size() > 0)
			{
				// Get first task
				Task task = tasks.get(0);
				this.setTaskId(task.getId());

				nextPage = QueryDao.getFormKey(this.getTaskId());
				System.out.println("Error nextPage: " + nextPage);
				
				//taskUI.setValue(task.getId());
				this.setTaskId(task.getId());
			}
			
			FacesContext fc = FacesContext.getCurrentInstance();
			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, taskError, null);
		    fc.addMessage(null, msg);
		    fc.renderResponse();
		}else{
				
			Address adr = null;
			adr = (Address)manager.getProcessEngine().getRuntimeService().getVariable(this.getInstanceId(), "address");
			
			
			if(adr!=null){
				this.setCustomerText("found Cit: " + adr.getCity());
				
				List<Task> tasks = manager.getProcessEngine().getTaskService().createTaskQuery().taskCandidateGroup(User.GROUP_DESKTOPWORKER).processInstanceId(instanceId).list();
				if (tasks.size() > 0)
				{
					// Get first task
					Task task = tasks.get(0);
					this.setTaskId(task.getId());
					//taskUI.setValue(task.getId());
					this.setTaskId(task.getId());
					
					nextPage = QueryDao.getFormKey(this.getTaskId());
					System.out.println("ADR Not Null nextPage: " + nextPage);
					
					manager.getTaskRuntimeService().complete(this.getTaskId());
					
					
					 // verify that the process is actually finished
				    HistoryService historyService = manager.getProcessEngine().getHistoryService();
				    HistoricProcessInstance historicProcessInstance = 
				      historyService.createHistoricProcessInstanceQuery().processInstanceId(this.instanceId).singleResult();
				    System.out.println("Process instance end time: " + historicProcessInstance.getEndTime());
					this.setFinishedText("Process instance end time: " + historicProcessInstance.getEndTime());
				}
				
			}else{
				
				List<Task> tasks = manager.getProcessEngine().getTaskService().createTaskQuery().taskCandidateGroup(User.GROUP_DESKTOPWORKER).processInstanceId(instanceId).list();
				if (tasks.size() > 0)
				{
					// Get first task
					Task task = tasks.get(0);
					this.setTaskId(task.getId());
					
					//nextPage = QueryDao.getFormKey(this.getTaskId());
					System.out.println("ADR Null nextPage: " + nextPage);
					
					//taskUI.setValue(task.getId());
					this.setTaskId(task.getId());
				}
				
				FacesContext fc = FacesContext.getCurrentInstance();
				FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "No customer found with this address.", null);
			    fc.addMessage(null, msg);
			    fc.renderResponse();
				
				this.setCustomerText("No such address found.");
			}
			
		}
		
		return WebUtils.redirect(nextPage);
	}
	
	
	public String showDesktopWorker(){
		return "showDesktopWorker";
	}
	
	public String showSupervisor(){
		return "showSupervisor";
	}
	
	public String showSurveyor(){
		return "showSurveyor";
	}
	
	

	public String getProcessInfo(Task task){
		ActivitiManager manager=ActivitiManager.getInstance();
		Object o=manager.getRuntimeService().getVariable(task.getExecutionId(), "test");
		
		if(o==null)
			return "";
		else
			return o.toString();
	}
	
	
	public String getProcId() {
		return procId;
	}

	public void setProcId(String procId) {
		this.procId = procId;
	}

	public List<Task> groupWorkerTasks() {
		if(this.user!=null){		
			List<Task> tasks = QueryDao.getAllTasksWithCandidateGroupAndNoAssignee(this.user.getUserGroup());
			return tasks;
		}
		return null;
	}
	
	
	public List<Task> tasksFromUser() {
		if(this.user!=null){	
			List<Task> tasks = QueryDao.getAllTasksWithAssignee(user.getUserName());
			return tasks;
		}
		return null;
	}

	public String getNickname() {
		return nickname;
	}

	public void setNickname(String nickname) {
		this.nickname = nickname;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String login(){
		
		
		if(RegisteredUsers.isRegistered(nickname, password)){
			this.user = RegisteredUsers.getUser(nickname, password);
			
			if(User.GROUP_DESKTOPWORKER.equalsIgnoreCase(user.getUserGroup())){
				return WebUtils.redirect("myTasks");
			} else if(User.GROUP_SUPERVISOR.equalsIgnoreCase(user.getUserGroup())){
				return WebUtils.redirect("showSupervisor");  //TODO
			} else if(User.GROUP_SURVEYOR.equalsIgnoreCase(user.getUserGroup())){
				return WebUtils.redirect("showSurveyor");  //TODO
			}
		}
		else{
			FacesContext fc = FacesContext.getCurrentInstance();
			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Password or User incorrect!", null);
		    fc.addMessage(null, msg);
		    fc.renderResponse();
		}
		
		return "";
	}
	
	public String logout(){
		this.nickname="b.mueller@realestate.com";
		this.password=null;
		this.user=null;
		
		return WebUtils.redirect("login");
	}
	

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}
	
	public void assignTaskToUserAction(Task task){  
		User user=new User("b.mueller@realestate.com","beate","Beate","Müller",User.GROUP_DESKTOPWORKER);
		
		if(task!=null){
			QueryDao.setAssigneeToTask(task,user.getUserName());
		}
			
    }
	
	public void unassignTask (Task task){  
		if(task!=null){
			QueryDao.unassignTask(task);
		}
			
    }
	
	public void handleTask (Task task){  
		if(task!=null){
			//TODO mit FormKey navigieren
			System.out.println(" --> "+QueryDao.getFormKey(task));
		}
			
    }
	
	public void abortProcess (Task task){  	
		if(task!=null){
			QueryDao.abortProcess(task);
		}
			
    }
	
	public void startProcess(){  
		ActivitiManager manager=ActivitiManager.getInstance();
		manager.deployProcess(Constants.DEPLOY_PROCESS);
		manager.startProcess();	
    }

	public Ticket getTicket() {
		return ticket;
	}

	public void setTicket(Ticket ticket) {
		this.ticket = ticket;
	}
	
	
}
